package org.cancan.demo.ws;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;

@Data
@ServerEndpoint("/img/{uuid}") //类似RequestMapping的地址
@Component
@Slf4j
public class WebSocketServer {

    /**
     *  与某个客户端的连接对话，需要通过它来给客户端发送消息
     */
    private Session session;

    /**
     * 标识当前连接客户端的用户名
     */
    private String uuid;

    //存放每个客户端的连接会话
    public static ConcurrentHashMap<String,WebSocketServer> clients = new ConcurrentHashMap<>();

    //开启连接
    @OnOpen
    public void onOpen(Session session, @PathParam( "uuid") String uuid){
        this.session = session;
        this.uuid = uuid;
        // name是用来表示唯一客户端，如果需要指定发送，需要指定发送通过name来区分
        clients.put(uuid,this);
        log.info("[WebSocket] 连接成功，当前连接人数为：={}",clients.size());
    }

    @OnMessage
    public void OnMessage(String msg, @PathParam( "uuid") String uuid){
        log.info("[WebSocket] 收到消息：{}",msg);
    }

    //关闭连接
    @OnClose
    public void onClose(@PathParam( "uuid") String uuid){
        clients.remove(uuid);
        log.info("[WebSocket] 退出成功，当前连接人数为：={}",clients.size());
    }

    //发生异常的情况
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
    }

    /**
     * 群发地址
     * @param message
     */
    public static void GroupSending(String message){
        for (String uuid : clients.keySet()){
            try {
                clients.get(uuid).session.getBasicRemote().sendText(message);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 群发地址
     * @param imageData
     */
    public static void GroupBinarySending(byte[] imageData){
        for (String uuid : clients.keySet()){
            try {
                clients.get(uuid).session.getBasicRemote().sendBinary(ByteBuffer.wrap(imageData));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}